package chpt_05_03_composite;


import java.awt.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Ping
 * @date 2023/4/13 8:31
 **/
public class CompositeDemo {
    public static void main(String args[]) {

        EatableFruit smallPlate = new FruitPlate() ;
        EatableFruit apple = new Apple() ;
        EatableFruit orange = new Orange() ;
        EatableFruit largePlate = new FruitPlate() ;
        /**
         * 结构的组合
         */
        smallPlate.add(apple) ;
        largePlate.add(smallPlate)
                    .add(smallPlate)
                    .add(orange) ;
        /**
         * 结构的使用
         */
        largePlate.eat() ;
    }
}
/**
 * 水果拼盘案例来演示组合模式
 */

interface EatableFruit {
    /**
     * add elements
     * @param fruit
     */
    public default  EatableFruit add(EatableFruit fruit) {
        return null ;
    }

    /**
     * common actions
     */
    public void eat() ;
}
/**
 * elements: composite element, and leaf element
 */

/**
 * composite element
 */
class FruitPlate implements EatableFruit {
    Component component ;
    protected List<EatableFruit> elements ;

    public FruitPlate() {
        this.elements = new ArrayList<>() ;
    }

    @Override
    public EatableFruit add(EatableFruit fruit) {
        this.elements.add(fruit) ;
        return this ;
    }
    @Override
    public void eat() {
        if (this.elements.size() > 0) {
            System.out.println("准备吃拼盘") ;
            this.elements.forEach(x -> x.eat());
            System.out.println("吃完一个拼盘") ;
        } else {
            System.out.println("暂无水果可吃！") ;
        }
    }
}

/**
 * leaf element
 */
class Apple implements EatableFruit {
    @Override
    public EatableFruit add(EatableFruit fruit) {
        try {
            throw new Exception("该水果支持添加其他水果！") ;
        } catch (Exception e){
            e.printStackTrace();
        }
        return null ;
    }

    @Override
    public void eat() {
        System.out.println("苹果很好吃！") ;
    }
}
class Orange implements EatableFruit {
    @Override
    public EatableFruit add(EatableFruit fruit) {
        try {
            throw new Exception("该水果支持添加其他水果！") ;
        } catch (Exception e){
            e.printStackTrace();
        }
        return null ;
    }

    @Override
    public void eat() {
        System.out.println("橘子很好吃！") ;
    }
}









